package com.ihg.hiex.admin.web.controller.account;

import java.util.List;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.collections.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import com.demo2do.core.entity.page.Page;
import com.demo2do.core.entity.result.HttpResult;
import com.demo2do.core.persistence.support.QueryOrder;
import com.demo2do.core.web.interceptor.MenuSetting;
import com.demo2do.core.web.resolver.Preloading;
import com.demo2do.core.web.utils.WebUtils;
import com.ihg.hiex.admin.entity.search.DelegateSearch;
import com.ihg.hiex.admin.service.account.DelegateService;
import com.ihg.hiex.admin.service.session.DelegateCoachingConversationService;
import com.ihg.hiex.admin.service.session.SessionDuringService;
import com.ihg.hiex.admin.service.session.SessionParticipatorService;
import com.ihg.hiex.admin.service.session.SessionReportService;
import com.ihg.hiex.admin.service.session.SessionService;
import com.ihg.hiex.entity.session.Session;
import com.ihg.hiex.entity.session.Status;
import com.ihg.hiex.entity.session.after.SessionReport;
import com.ihg.hiex.entity.session.during.SessionCalibration;
import com.ihg.hiex.entity.session.during.SessionCalibrationRecommendation;
import com.ihg.hiex.entity.session.during.report.SessionReportWriting;
import com.ihg.hiex.entity.session.participator.SessionParticipator;
import com.ihg.hiex.entity.user.Delegate;
import com.ihg.hiex.entity.user.DelegateCoachingConversation;

/**
 * 
 * @author houtao
 *
 */
@Controller
@RequestMapping("/delegates")
@MenuSetting("menu-settings")
public class DelegateController {

    private static final Logger logger = LoggerFactory.getLogger(DelegateController.class);

    @Autowired
    private DelegateService delegateService;
    
    @Autowired
    private SessionService sessionService;
    
    @Autowired
    private SessionParticipatorService sessionParticipatorService;
    
    @Autowired
    private DelegateCoachingConversationService delegateCoachingConversationService;
    
    @Autowired
    private SessionDuringService sessionDuringService;
    
    @Autowired
    private SessionReportService sessionReportService;

    /**
     * list delegate by page
     * 
     * @param page
     * @return
     */
    @MenuSetting("submenu-delegate-management")
    @RequestMapping(value = "", method = RequestMethod.GET)
    public ModelAndView list(Page page) {

        ModelAndView modelAndView = new ModelAndView("account/delegate/delegate-list");

        int totals = delegateService.count(Delegate.class);
        if (totals > 0) {

            QueryOrder queryOrder = new QueryOrder("lastModifyTime", "DESC");
            List<Delegate> delegates = delegateService.listByPage(Delegate.class, queryOrder, page.with(totals));

            modelAndView.addObject("delegates", delegates);
            modelAndView.addObject("page", page);
            
        }
        
        return modelAndView;
        
    }

    /**
     * display search panel
     * 
     * @return
     */
    @RequestMapping(value = "/search", method = RequestMethod.GET)
    public String search() {
        return "account/delegate/delegate-search";
    }

    /**
     * on search delegate
     * 
     * @param search
     * @param page
     * @param request
     * @return
     */
    @RequestMapping(value = "", method = RequestMethod.GET, params = "filter")
    @MenuSetting("submenu-delegate-management")
    public ModelAndView onSearch(DelegateSearch search, Page page, HttpServletRequest request) {

        ModelAndView modelAndView = new ModelAndView("account/delegate/delegate-list");

        int totals = delegateService.count(Delegate.class, search.getPreparedFilter(false));
        if (totals > 0) {

            List<Delegate> delegates = delegateService.search(Delegate.class, search, page.with(totals));
            modelAndView.addObject("delegates", delegates);
            
            modelAndView.addObject("page", page);
            modelAndView.addObject("queryString", WebUtils.extractQueryString(request, "page", "filter"));
            
        }

        return modelAndView;
        
    }

    /**
     * view delegate
     * 
     * @param id
     * @return
     */
    @RequestMapping(value = "/{id}", method = RequestMethod.GET)
    @MenuSetting("submenu-delegate-management")
    public ModelAndView view(@PathVariable("id") Long id) {

        ModelAndView modelAndView = new ModelAndView("account/delegate/delegate-view");

        // 1. load delegate
        Delegate delegate = delegateService.load(Delegate.class, id);
        modelAndView.addObject("delegate", delegate);
        
        // 2. load current session
        List<Session> sessions = sessionService.list(Status.ACTIVE, delegate);
        Session session = CollectionUtils.isNotEmpty(sessions) ? sessions.get(0) : null;
        modelAndView.addObject("session", session);
        
        // load sessionParticipator
        SessionParticipator participator = sessionParticipatorService.loadByDelegate(session, id);
        modelAndView.addObject("participator", participator);
        
        SessionReport sessionReport = sessionReportService.load(session, delegate);
        modelAndView.addObject("sessionReport", sessionReport);
        
        if(session.getSessionPhase().isAfter()) {
            // list conversation
            List<DelegateCoachingConversation> conversations = delegateCoachingConversationService.list(delegate);
            modelAndView.addObject("conversations", conversations);
        }
        
        SessionCalibration sessionCalibration = sessionDuringService.loadSessionCalibration(session, delegate);
        modelAndView.addObject("sessionCalibration", sessionCalibration);
        
        if(sessionCalibration != null) {
            SessionReportWriting reportWriting = sessionReportService.loadReportWriting(sessionCalibration);
            modelAndView.addObject("reportWriting", reportWriting);
            
            if(reportWriting == null) {
                SessionCalibrationRecommendation recommendation = sessionDuringService.loadSessionCalibrationRecommendation(sessionCalibration);
                modelAndView.addObject("recommendation", recommendation);
            }
        }
        
        return modelAndView;
        
    }
    
    /**
     * prepare to edit delegate
     * 
     * @param id
     * @return
     */
    @RequestMapping(value = "/{id}/edit", method = RequestMethod.GET)
    public ModelAndView edit(@PathVariable("id") Long id) {

        ModelAndView modelAndView = new ModelAndView("account/delegate/delegate-edit");

        Delegate delegate = delegateService.load(Delegate.class, id);

        modelAndView.addObject("delegate", delegate);

        return modelAndView;
    }

    /**
     * edit delegate
     * 
     * @param delegate
     * @return
     */
    @RequestMapping(value = "/{id}/edit", method = RequestMethod.PATCH, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public @ResponseBody HttpResult onEdit(@Preloading("delegateId") Delegate delegate) {

        HttpResult httpResult = new HttpResult();
        
        try {

            delegateService.edit(delegate);

            httpResult.success().message("编辑成功");

        } catch (Exception e) {
            httpResult.fail("500").message("编辑失败");
            logger.error("#onEdit() - edit fail, exception is [{}]", e);
        }
        
        return httpResult;
        
    }

    /**
     * display delete panel
     * 
     * @param id
     * @return
     */
    @RequestMapping(value = "/{id}/delete", method = RequestMethod.GET)
    public ModelAndView delete(@PathVariable("id") Long id) {

        ModelAndView modelAndView = new ModelAndView("account/delegate/delegate-delete");

        modelAndView.addObject("id", id);

        return modelAndView;
    }

    /**
     * delete delegate
     * 
     * @param id
     * @return
     */
    @RequestMapping(value = "/{id}", method = RequestMethod.DELETE, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public @ResponseBody HttpResult onDetele(@PathVariable("id") Long id) {

        HttpResult httpResult = new HttpResult();

        try {

            Delegate delegate = delegateService.load(Delegate.class, id);
            delegateService.disable(delegate);

            httpResult.success().message("删除成功");

        } catch (Exception e) {
            httpResult.fail("500").message("删除失败");
            logger.error("#onDelete() - delete fail, exception is [{}]", e);
        }
        
        return httpResult;
        
    }

}